/**
 * 用户活跃度跟踪服务
 * 用于记录和统计用户活动数据，包括使用时长、消息统计等
 */

const models = require('../models');
const logger = require('../utils/logger');
const moment = require('moment');
const { Sequelize } = require('sequelize');
const cacheService = require('./cacheService');

/**
 * 创建用户会话记录
 * @param {number} userId 用户ID
 * @param {string} sessionToken 会话令牌
 * @param {string} ipAddress IP地址
 * @param {string} userAgent 用户代理
 * @returns {Promise<object>} 创建的会话记录
 */
const createUserSession = async (userId, sessionToken, ipAddress, userAgent) => {
  const transaction = await models.sequelize.transaction();
  
  try {
    // 检查参数有效性
    if (!userId || !sessionToken) {
      throw new Error('用户ID和会话令牌不能为空');
    }
    
    // 检查是否有未关闭的会话，如有则先关闭
    const activeSessions = await models.UserSession.findAll({
      where: {
        userId,
        status: ['active', 'idle']
      },
      transaction
    });

    if (activeSessions && activeSessions.length > 0) {
      logger.info(`用户 ${userId} 有 ${activeSessions.length} 个活跃会话，将自动结束`);
      for (const session of activeSessions) {
        await endUserSession(session.id, 'new_login', transaction);
      }
    }

    // 创建新会话
    const session = await models.UserSession.create({
      userId,
      sessionToken,
      startTime: new Date(),
      status: 'active',
      ipAddress,
      userAgent,
      lastActivityTime: new Date()
    }, { transaction });

    // 更新用户最后登录时间
    await models.User.update(
      { lastLoginAt: new Date() },
      { 
        where: { id: userId },
        transaction
      }
    );

    // 获取或创建今日的活跃度记录
    const today = moment().format('YYYY-MM-DD');
    const [activity] = await models.UserActivity.findOrCreate({
      where: {
        userId,
        date: today
      },
      defaults: {
        userId,
        date: today,
        activeTime: 0,
        messagesSent: 0,
        messagesReceived: 0,
        sessionStarts: 1,
        loginTime: new Date()
      },
      transaction
    });

    // 如果记录已存在，增加会话计数
    if (activity && activity.id) {
      await activity.increment('sessionStarts', { transaction });
      
      // 只有在首次登录时间为空时才更新
      if (!activity.loginTime) {
        await activity.update({ loginTime: new Date() }, { transaction });
      }
    }

    await transaction.commit();
    return session;
  } catch (error) {
    await transaction.rollback();
    logger.error('创建用户会话失败:', error);
    throw error;
  }
};

/**
 * 结束用户会话
 * @param {number} sessionId 会话ID
 * @param {string} reason 关闭原因
 * @param {import('sequelize').Transaction} [externalTransaction] 外部事务对象
 * @returns {Promise<object>} 更新后的会话记录
 */
const endUserSession = async (sessionId, reason = 'logout', externalTransaction = null) => {
  let transaction = externalTransaction;
  let shouldCommit = false;
  
  if (!transaction) {
    transaction = await models.sequelize.transaction();
    shouldCommit = true;
  }
  
  try {
    const session = await models.UserSession.findByPk(sessionId, { transaction });
    if (!session) {
      logger.warn(`会话不存在: ${sessionId}`);
      if (shouldCommit) await transaction.rollback();
      throw new Error(`会话不存在: ${sessionId}`);
    }

    // 只有活跃会话才能被关闭
    if (session.status !== 'active' && session.status !== 'idle') {
      logger.info(`会话 ${sessionId} 已经处于 ${session.status} 状态，不需要关闭`);
      if (shouldCommit) await transaction.commit();
      return session;
    }

    const now = new Date();
    const startTime = new Date(session.startTime);
    const duration = Math.floor((now - startTime) / 1000); // 计算秒数

    // 计算活跃时间占比
    const activeTimePercentage = session.activeTime > 0 && duration > 0
      ? (session.activeTime / duration) * 100
      : 0;
    
    logger.info(`会话 ${sessionId} 结束, 总时长: ${duration}秒, 活跃时间: ${session.activeTime}秒 (${activeTimePercentage.toFixed(1)}%)`);

    // 更新会话记录
    await session.update({
      endTime: now,
      duration,
      status: 'closed',
      closeReason: reason,
      idleTime: duration - (session.activeTime || 0)
    }, { transaction });

    // 更新当日活跃度记录的登出时间
    const today = moment().format('YYYY-MM-DD');
    const activity = await models.UserActivity.findOne({
      where: {
        userId: session.userId,
        date: today
      },
      transaction
    });

    if (activity) {
      await activity.update({ logoutTime: now }, { transaction });
    }

    if (shouldCommit) await transaction.commit();
    return session;
  } catch (error) {
    if (shouldCommit) await transaction.rollback();
    logger.error('结束用户会话失败:', error);
    throw error;
  }
};

/**
 * 更新用户活跃时间
 * @param {number} userId 用户ID
 * @param {number} sessionId 会话ID
 * @param {number} seconds 活跃秒数
 * @returns {Promise<object>} 更新结果
 */
const updateActiveTime = async (userId, sessionId, seconds) => {
  try {
    // 验证参数
    if (!userId || !sessionId || seconds <= 0) {
      logger.warn('更新活跃时间参数无效:', { userId, sessionId, seconds });
      return { success: false, message: '参数无效' };
    }

    // 验证会话存在且状态为活跃
    const session = await models.UserSession.findOne({
      where: {
        id: sessionId,
        userId,
        status: ['active', 'idle']
      }
    });

    if (!session) {
      logger.warn('会话不存在或已关闭:', { sessionId, userId });
      return { success: false, message: '会话不存在或已关闭' };
    }

    // 更新会话的活跃时间和最后活跃时间
    await session.increment('activeTime', { by: seconds });
    await session.update({
      lastActivityTime: new Date(),
      status: 'active' // 如果之前是idle状态，恢复为active
    });

    // 更新当日活跃度记录
    const today = moment().format('YYYY-MM-DD');
    const [activity] = await models.UserActivity.findOrCreate({
      where: {
        userId,
        date: today
      },
      defaults: {
        userId,
        date: today,
        activeTime: seconds,
        sessionStarts: 1
      }
    });

    // 如果记录已存在，增加活跃时间
    if (activity && activity.id) {
      await activity.increment('activeTime', { by: seconds });
    }

    return {
      success: true,
      activeTime: (session.activeTime || 0) + seconds,
      lastActiveTime: new Date()
    };
  } catch (error) {
    logger.error('更新用户活跃时间失败:', error);
    return { success: false, message: error.message };
  }
};

/**
 * 标记会话为空闲状态
 * @param {number} sessionId 会话ID
 * @returns {Promise<object>} 更新结果
 */
const markSessionAsIdle = async (sessionId) => {
  try {
    const session = await models.UserSession.findByPk(sessionId);
    if (!session || session.status !== 'active') {
      return { success: false, message: '会话不存在或非活跃状态' };
    }

    await session.update({
      status: 'idle'
    });

    return { success: true };
  } catch (error) {
    logger.error('标记会话为空闲状态失败:', error);
    return { success: false, message: error.message };
  }
};

/**
 * 记录消息发送
 * @param {number} userId 用户ID
 * @param {string} contactId 联系人ID
 * @returns {Promise<object>} 更新结果
 */
const recordMessageSent = async (userId, contactId) => {
  try {
    // 更新当日活跃度记录
    const today = moment().format('YYYY-MM-DD');
    const [activity] = await models.UserActivity.findOrCreate({
      where: {
        userId,
        date: today
      },
      defaults: {
        userId,
        date: today,
        activeTime: 0,
        messagesSent: 1,
        messagesReceived: 0
      }
    });

    // 如果记录已存在，增加发送消息计数
    if (activity && activity.id) {
      await activity.increment('messagesSent');
    }

    // 查找活跃会话并更新
    const session = await models.UserSession.findOne({
      where: {
        userId,
        status: ['active', 'idle']
      },
      order: [['startTime', 'DESC']]
    });

    if (session) {
      await session.increment('messagesSent');
      await session.update({
        lastActivityTime: new Date(),
        status: 'active' // 确保状态为活跃
      });
    }

    return { success: true };
  } catch (error) {
    logger.error('记录消息发送失败:', error);
    return { success: false, message: error.message };
  }
};

/**
 * 记录消息接收
 * @param {number} userId 用户ID
 * @param {string} contactId 联系人ID
 * @returns {Promise<object>} 更新结果
 */
const recordMessageReceived = async (userId, contactId) => {
  try {
    // 更新当日活跃度记录
    const today = moment().format('YYYY-MM-DD');
    const [activity] = await models.UserActivity.findOrCreate({
      where: {
        userId,
        date: today
      },
      defaults: {
        userId,
        date: today,
        activeTime: 0,
        messagesSent: 0,
        messagesReceived: 1
      }
    });

    // 如果记录已存在，增加接收消息计数
    if (activity && activity.id) {
      await activity.increment('messagesReceived');
    }

    // 查找活跃会话并更新
    const session = await models.UserSession.findOne({
      where: {
        userId,
        status: ['active', 'idle']
      },
      order: [['startTime', 'DESC']]
    });

    if (session) {
      await session.increment('messagesReceived');
    }

    return { success: true };
  } catch (error) {
    logger.error('记录消息接收失败:', error);
    return { success: false, message: error.message };
  }
};

/**
 * 记录WhatsApp会话开始
 * @param {number} userId 用户ID
 * @param {string} sessionId WhatsApp会话ID
 * @param {string} phoneNumber 电话号码
 * @returns {Promise<object>} 创建的WhatsApp会话记录
 */
const recordWhatsAppSessionStart = async (userId, sessionId, phoneNumber) => {
  const transaction = await models.sequelize.transaction();
  
  try {
    // 参数验证
    if (!userId || !sessionId) {
      throw new Error('用户ID和会话ID不能为空');
    }
    
    // 检查是否有未关闭的会话，如有则先关闭
    const activeSessions = await models.WhatsAppSession.findAll({
      where: {
        userId,
        status: 'connected'
      },
      transaction
    });

    if (activeSessions && activeSessions.length > 0) {
      logger.info(`用户 ${userId} 有 ${activeSessions.length} 个活跃WhatsApp会话，将自动结束`);
      for (const session of activeSessions) {
        await recordWhatsAppSessionEnd(session.id, transaction);
      }
    }

    // 创建新会话
    const session = await models.WhatsAppSession.create({
      userId,
      sessionId,
      status: 'connected',
      startTime: new Date(),
      phoneNumber,
      lastActivityTime: new Date()
    }, { transaction });

    // 更新用户的WhatsApp状态
    await models.User.update(
      { 
        whatsappStatus: 'connected',
        whatsappId: phoneNumber
      },
      { 
        where: { id: userId },
        transaction
      }
    );
    
    logger.info(`用户 ${userId} 的WhatsApp会话 ${sessionId} 已开始，关联号码: ${phoneNumber || '未知'}`);

    await transaction.commit();
    return session;
  } catch (error) {
    await transaction.rollback();
    logger.error('记录WhatsApp会话开始失败:', error);
    throw error;
  }
};

/**
 * 记录WhatsApp会话结束
 * @param {number} sessionId 会话ID
 * @param {import('sequelize').Transaction} [externalTransaction] 外部事务对象
 * @returns {Promise<object>} 更新后的会话记录
 */
const recordWhatsAppSessionEnd = async (sessionId, externalTransaction = null) => {
  let transaction = externalTransaction;
  let shouldCommit = false;
  
  if (!transaction) {
    transaction = await models.sequelize.transaction();
    shouldCommit = true;
  }
  
  try {
    const session = await models.WhatsAppSession.findByPk(sessionId, { transaction });
    if (!session) {
      logger.warn(`WhatsApp会话不存在: ${sessionId}`);
      if (shouldCommit) await transaction.rollback();
      throw new Error(`WhatsApp会话不存在: ${sessionId}`);
    }

    // 只有连接状态的会话才能被关闭
    if (session.status !== 'connected') {
      logger.info(`WhatsApp会话 ${sessionId} 已经处于 ${session.status} 状态，不需要关闭`);
      if (shouldCommit) await transaction.commit();
      return session;
    }

    const now = new Date();
    const startTime = new Date(session.startTime);
    const duration = Math.floor((now - startTime) / 1000); // 计算秒数

    // 更新会话记录
    await session.update({
      endTime: now,
      duration,
      status: 'disconnected'
    }, { transaction });

    // 更新用户的WhatsApp状态
    await models.User.update(
      { whatsappStatus: 'disconnected' },
      { 
        where: { id: session.userId },
        transaction
      }
    );
    
    logger.info(`用户 ${session.userId} 的WhatsApp会话 ${sessionId} 已结束，持续时间: ${duration}秒`);

    if (shouldCommit) await transaction.commit();
    return session;
  } catch (error) {
    if (shouldCommit) await transaction.rollback();
    logger.error('记录WhatsApp会话结束失败:', error);
    throw error;
  }
};

/**
 * 获取用户当日活跃度数据
 * @param {number} userId 用户ID
 * @returns {Promise<object>} 活跃度数据
 */
const getUserDailyActivity = async (userId) => {
  try {
    const today = moment().format('YYYY-MM-DD');
    const activity = await models.UserActivity.findOne({
      where: {
        userId,
        date: today
      }
    });

    if (!activity) {
      return {
        userId,
        date: today,
        activeTime: 0,
        messagesSent: 0,
        messagesReceived: 0,
        sessionStarts: 0
      };
    }

    return activity;
  } catch (error) {
    logger.error('获取用户当日活跃度数据失败:', error);
    throw error;
  }
};

/**
 * 获取用户活跃度历史数据
 * @param {number} userId 用户ID
 * @param {string} startDate 开始日期 (YYYY-MM-DD)
 * @param {string} endDate 结束日期 (YYYY-MM-DD)
 * @returns {Promise<Array>} 活跃度数据列表
 */
const getUserActivityHistory = async (userId, startDate, endDate) => {
  try {
    // 如果未提供日期，默认查询最近7天
    if (!startDate) {
      startDate = moment().subtract(6, 'days').format('YYYY-MM-DD');
    }
    if (!endDate) {
      endDate = moment().format('YYYY-MM-DD');
    }

    const activities = await models.UserActivity.findAll({
      where: {
        userId,
        date: {
          [models.Sequelize.Op.between]: [startDate, endDate]
        }
      },
      order: [['date', 'ASC']]
    });

    return activities;
  } catch (error) {
    logger.error('获取用户活跃度历史数据失败:', error);
    throw error;
  }
};

/**
 * 获取所有用户的活跃度统计
 * @param {string} date 日期 (YYYY-MM-DD)，默认为今天
 * @returns {Promise<Array>} 用户活跃度统计列表
 */
const getAllUsersActivity = async (date) => {
  try {
    // 如果未提供日期，默认查询今天
    if (!date) {
      date = moment().format('YYYY-MM-DD');
    }

    // 获取所有活跃用户
    const activities = await models.UserActivity.findAll({
      where: {
        date
      },
      include: [
        {
          model: models.User,
          as: 'user',
          attributes: ['id', 'username', 'name', 'role', 'department', 'whatsappStatus']
        }
      ],
      order: [['activeTime', 'DESC']]
    });

    return activities;
  } catch (error) {
    logger.error('获取所有用户活跃度统计失败:', error);
    throw error;
  }
};

/**
 * 获取用户活跃度报告
 * @param {number} userId 用户ID
 * @param {string} period 周期 (day, week, month)
 * @returns {Promise<object>} 活跃度报告
 */
const getUserActivityReport = async (userId, period = 'week') => {
  try {
    // 创建缓存键
    const cacheKey = `activity:report:${userId}:${period}`;
    
    // 尝试从缓存获取数据
    const cachedData = await cacheService.get(cacheKey);
    if (cachedData) {
      logger.info(`从缓存获取用户${userId}的活跃度报告`);
      return cachedData;
    }
    
    let startDate;
    const endDate = moment().format('YYYY-MM-DD');

    // 根据周期确定开始日期
    switch (period) {
      case 'day':
        startDate = endDate;
        break;
      case 'week':
        startDate = moment().subtract(6, 'days').format('YYYY-MM-DD');
        break;
      case 'month':
        startDate = moment().subtract(29, 'days').format('YYYY-MM-DD');
        break;
      default:
        startDate = moment().subtract(6, 'days').format('YYYY-MM-DD');
    }

    // 获取活跃度数据
    const activities = await models.UserActivity.findAll({
      where: {
        userId,
        date: {
          [models.Sequelize.Op.between]: [startDate, endDate]
        }
      },
      order: [['date', 'ASC']]
    });

    // 获取用户信息
    const user = await models.User.findByPk(userId);

    // 计算汇总数据
    let totalActiveTime = 0;
    let totalMessagesSent = 0;
    let totalMessagesReceived = 0;
    let totalSessionStarts = 0;

    activities.forEach(activity => {
      totalActiveTime += activity.activeTime || 0;
      totalMessagesSent += activity.messagesSent || 0;
      totalMessagesReceived += activity.messagesReceived || 0;
      totalSessionStarts += activity.sessionStarts || 0;
    });

    // 计算平均响应率
    const responseRate = activities.reduce((sum, activity) => {
      return sum + (activity.responseRate || 0);
    }, 0) / (activities.length || 1);

    // 计算平均响应时间
    const averageResponseTime = activities.reduce((sum, activity) => {
      return sum + (activity.averageResponseTime || 0);
    }, 0) / (activities.length || 1);

    const result = {
      user: {
        id: user.id,
        username: user.username,
        name: user.name,
        role: user.role,
        department: user.department,
        whatsappStatus: user.whatsappStatus
      },
      period: {
        startDate,
        endDate,
        type: period
      },
      summary: {
        totalActiveTime,
        totalMessagesSent,
        totalMessagesReceived,
        totalSessionStarts,
        responseRate: parseFloat(responseRate.toFixed(2)),
        averageResponseTime: Math.round(averageResponseTime)
      },
      details: activities.map(activity => ({
        date: activity.date,
        activeTime: activity.activeTime || 0,
        messagesSent: activity.messagesSent || 0,
        messagesReceived: activity.messagesReceived || 0,
        sessionStarts: activity.sessionStarts || 0,
        responseRate: activity.responseRate || 0,
        averageResponseTime: activity.averageResponseTime || 0
      }))
    };
    
    // 缓存结果 - 设置不同的过期时间
    const cacheTime = period === 'day' ? 300 : (period === 'week' ? 1800 : 3600);
    await cacheService.set(cacheKey, result, cacheTime);
    
    return result;
  } catch (error) {
    logger.error('获取用户活跃度报告失败:', error);
    throw error;
  }
};

/**
 * 获取所有用户的活跃度报告
 * @param {string} period 周期 (day, week, month)
 * @returns {Promise<Array>} 活跃度报告列表
 */
const getAllUsersActivityReport = async (period = 'week') => {
  try {
    // 创建缓存键
    const cacheKey = `activity:report:all:${period}`;
    
    // 尝试从缓存获取数据
    const cachedData = await cacheService.get(cacheKey);
    if (cachedData) {
      logger.info(`从缓存获取所有用户的活跃度报告`);
      return cachedData;
    }
    
    // 获取所有用户
    const users = await models.User.findAll({
      where: {
        status: 'active',
        role: 'sales' // 只统计销售人员
      }
    });

    // 获取每个用户的活跃度报告
    const reports = await Promise.all(
      users.map(user => getUserActivityReport(user.id, period))
    );
    
    // 缓存结果
    const cacheTime = period === 'day' ? 300 : (period === 'week' ? 1800 : 3600);
    await cacheService.set(cacheKey, reports, cacheTime);
    
    return reports;
  } catch (error) {
    logger.error('获取所有用户活跃度报告失败:', error);
    throw error;
  }
};

// 导出服务函数
module.exports = {
  createUserSession,
  endUserSession,
  updateActiveTime,
  markSessionAsIdle,
  recordMessageSent,
  recordMessageReceived,
  recordWhatsAppSessionStart,
  recordWhatsAppSessionEnd,
  getUserDailyActivity,
  getUserActivityHistory,
  getAllUsersActivity,
  getUserActivityReport,
  getAllUsersActivityReport
}; 